var Click2TabLoadBookmark = 
{
    init : function ()
    {
        TMP_Bookmark.init();

        eval("BookmarksMenu.loadBookmark = " + BookmarksMenu.loadBookmark.toString().replace(
          'var browserTarget = whereToOpenLink(aEvent);',
          'var browserTarget = whereToOpenLinkTabmix(aEvent, prefStringTMBookmark, selection, aDS);'
        ));
    },

    deinit : function ()
    {
        TMP_Bookmark.deinit();

        eval("BookmarksMenu.loadBookmark = " + BookmarksMenu.loadBookmark.toString().replace(
          'var browserTarget = whereToOpenLinkTabmix(aEvent, prefStringTMBookmark, selection, aDS);',
          'var browserTarget = whereToOpenLink(aEvent);'
        ));
    }
}

// this code is call from firefox and from bookmark manager
var TMP_Bookmark = 
{
  _openGroupBookmark: null,
  init : function ()
  {
    this._openGroupBookmark = BookmarksCommand.openGroupBookmark;
    BookmarksCommand.openGroupBookmark = this.TMP_openGroupBookmark;

    eval("BookmarksCommand.createContextMenu ="+BookmarksCommand.createContextMenu.toString().replace(
      'popup.firstChild.setAttribute("default", "true");',
      'var where = TMP_whereToOpen("extensions.tabmix.opentabfor.bookmarks"); \
       var singlemode = PREF.getBoolPref("extensions.tabmix.singleWindow"); \
       popup.childNodes[1].hidden = singlemode; \
       if(popup.childNodes[2].getAttribute("command") == "cmd_bm_openinnewtab") \
         popup.childNodes[2].setAttribute("default", where.inNew); \
       if (where.lock) popup.firstChild.hidden = true; \
       else popup.firstChild.setAttribute("default", !where.inNew);'
    ));
  },

  deinit : function ()
  {
    BookmarksCommand.openGroupBookmark = this._openGroupBookmark;
  },

  TMP_openGroupBookmark: function (aURI, aTargetBrowser)
  {
    var resource = RDF.GetResource(aURI);
    var urlArc   = RDF.GetResource(NC_NS_TM+"URL"); // gNC_NS isn't for 1.0.7
    RDFC.Init(BMDS, resource);
    var containerChildren = RDFC.GetElements();

    var res, target, bmGroup = [];

    while (containerChildren.hasMoreElements()) {
       res = containerChildren.getNext().QueryInterface(kRDFRSCIID);
       target = BMDS.GetTarget(res, urlArc, true);
       if (target)
          bmGroup.push(target.QueryInterface(kRDFLITIID).Value);
    }
    
    // If the bookmark group was completely invalid, just bail.
    if (bmGroup.length != 0) {
       if ("_confirmOpenTabs" in this && !this._confirmOpenTabs(bmGroup.length))
          return;    

       TMP_Bookmark.openGroup(bmGroup, aTargetBrowser, true)
    }

  },

  // fixed: reuse all blank tab not just in the end
  // fixed: if "browser.tabs.loadFolderAndReplace" is true don't reuse locked and protected tabs open bookmark after those tabs
  // fixed: focus the first tab if "extensions.tabmix.openTabNext" is true
  // fixed: remove "selected" and "flst_id" from reuse tab
  openGroup: function (bmGroup, aTargetBrowser, isFolder)
  {
    var w = getTopWin();
    if (!w)
      // no browser window is open, we have to open the group into a new window
      aTargetBrowser = "window";

    if (aTargetBrowser == "current" || aTargetBrowser == "tab") {
      var browser  = w.document.getElementById("content");
      var tabs = browser.mTabContainer.childNodes;

      var _PREF = Components.classes["@mozilla.org/preferences-service;1"]
                  .getService(Components.interfaces.nsIPrefBranch);
      var doReplace = isFolder && _PREF.getBoolPref("browser.tabs.loadFolderAndReplace");
      var loadInBackground = _PREF.getBoolPref("browser.tabs.loadBookmarksInBackground");
      var openTabNext = _PREF.getBoolPref("extensions.tabmix.openTabNext");

      // catch tab for reuse
      var aTab, reuseTabs = [], removeTabs = [], i;
      var tabIsBlank, canReplace;
      for (i = 0; i < tabs.length ; i++) {
         aTab = tabs[i];
         tabIsBlank = browser.isBlankTab(aTab) && !aTab.hasAttribute("busy");
         canReplace = (doReplace && !aTab.hasAttribute("locked")) || tabIsBlank;
         if (reuseTabs.length < bmGroup.length && canReplace)
            reuseTabs.push(aTab);
         else if ((doReplace && !aTab.hasAttribute("locked") && !aTab.hasAttribute("protected")) || tabIsBlank)
            removeTabs.push(aTab);
      }

      var tabToSelect = null;
      var prevTab = (!doReplace && openTabNext && browser.mCurrentTab._tPos < tabs.length - 1) ? browser.mCurrentTab : browser.mTabContainer.lastChild;
      var prevTab0 = prevTab;
      var tabPos, index;
      for (i = 0; i < bmGroup.length ; i++) {
         if (i < reuseTabs.length) {
            aTab = reuseTabs[i];
            browser.getBrowserForTab(aTab).loadURI(bmGroup[i]);
            // reset selected & flst_id attribute
            if (aTab != browser.mCurrentTab) {
               aTab.removeAttribute("selected");
               aTab.removeAttribute("flst_id");
            } else
               aTab.setAttribute("reloadcurrent", true);
         }
         else
            aTab = browser.addTab(bmGroup[i]);

         if (!tabToSelect) 
            tabToSelect = aTab;
         // move tab to place
         index = prevTab._tPos + 1;
         tabPos = (aTab._tPos < index && index < tabs.length - 1) ? index - 1 : index;
         browser.TMmoveTabTo(aTab, tabPos);
         prevTab = aTab;
      }
      browser.mTabContainer.nextTab = 1;

      // focus the first tab if prefs say to
      if (!loadInBackground || doReplace) {
        // Select the first tab in the group.
        // Set newly selected tab after quick timeout, otherwise hideous focus problems
        // can occur because new presshell is not ready to handle events
        function selectNewForegroundTab(browser, tab) {
          var old = browser.selectedTab;
          browser.selectedTab = tab;

          var reloadCurrent = old.hasAttribute("reloadcurrent");
          if (reloadCurrent) 
            old.removeAttribute("reloadcurrent");
          if (reloadCurrent && old != tab) {
            old.removeAttribute("selected");
            old.removeAttribute("flst_id");
          }
        }
        setTimeout(selectNewForegroundTab, 0, browser, tabToSelect);
      }

      // Close any remaining open tabs or blank tabs that are left over.
      while (removeTabs.length > 0) {
         browser.removeTab(removeTabs.pop());
      }

      // and focus the content
      w.content.focus();

    } else if (aTargetBrowser == "window")
      openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no", bmGroup.join("|"));

  },

   _getBookmarkTitle: function (url)
   {
      if(! BMSVC || ! BMDS || ! RDF) return null;
      var urlArc = RDF.GetResource(NC_NS_TM+"URL");
      var urlLiteral = RDF.GetLiteral(url);
      if (BMDS.hasArcIn(urlLiteral, urlArc)) {
         var bmResources, bmResource, title, type, ptype;
         bmResources = BMSVC.GetSources(urlArc, urlLiteral, true);
         while (bmResources.hasMoreElements()) {
            bmResource = bmResources.getNext();
            type = BookmarksUtils.resolveType(bmResource);
            if (type != "ImmutableBookmark") {
               ptype = BookmarksUtils.resolveType(BMSVC.getParent(bmResource));
               if ( (type == "Bookmark" || type == "IEFavorite") &&  ptype != "Livemark") {
                  title = BookmarksUtils.getProperty(bmResource, NC_NS_TM+"Name");
                  if (title != "") return title;
               }
            }
         }
      }
      return null;
   }

}
